package msgdef

import (
	"encoding/binary"
	"fmt"
	"src/zeus/bytestream"
)

// EnterSpaceReq 请求进入空间
type EnterSpaceReq struct {
	SrvID      uint64
	SpaceID    uint64
	EntityType string
	EntityID   uint64
	DBID       uint64
	InitParam  []byte
	OldSrvID   uint64
	OldSpaceID uint64
}

func (msg *EnterSpaceReq) String() string {
	return fmt.Sprintf("%+v", *msg)
}

// Name 获取消息名称
func (msg *EnterSpaceReq) Name() string {
	return "EnterSpaceReq"
}

// MarshalTo 序列化
func (msg *EnterSpaceReq) MarshalTo(data []byte) (n int, err error) {
	bw := bytestream.NewByteStream(data)
	return msg.Size(), bw.Marshal(msg)
}

// Unmarshal 反序列化
func (msg *EnterSpaceReq) Unmarshal(data []byte) error {
	br := bytestream.NewByteStream(data)
	return br.Unmarshal(msg)
}

// Size 获取长度
// 8 + 8 + 2 + len(string) + 8 + 8 + 8 + 8
func (msg *EnterSpaceReq) Size() (n int) {
	//return 50 + len(msg.EntityType)
	return bytestream.CalcSize(msg)
}

//////////////////////////////////////////////////////////////

// LeaveSpaceReq 请求离开空间
type LeaveSpaceReq struct {
	EntityID uint64
}

func (msg *LeaveSpaceReq) String() string {
	return fmt.Sprintf("%+v", *msg)
}

// Name 获取消息名称
func (msg *LeaveSpaceReq) Name() string {
	return "LeaveSpaceReq"
}

// MarshalTo 序列化
func (msg *LeaveSpaceReq) MarshalTo(data []byte) (n int, err error) {
	binary.LittleEndian.PutUint64(data[0:8], msg.EntityID)
	return msg.Size(), nil
}

// Unmarshal 反序列化
func (msg *LeaveSpaceReq) Unmarshal(data []byte) error {
	msg.EntityID = binary.LittleEndian.Uint64(data[0:8])
	return nil
}

// Size 获取长度
func (msg *LeaveSpaceReq) Size() (n int) {
	return 8
}

// SpaceUserConnect 空间玩家专用连接成功，由客户端发给服务器
type SpaceUserConnect struct {
	UID     uint64
	SpaceID uint64
}

func (msg *SpaceUserConnect) String() string {
	return fmt.Sprintf("%+v", *msg)
}

// Name 获取消息名称
func (msg *SpaceUserConnect) Name() string {
	return "SpaceUserConnect"
}

// MarshalTo 序列化
func (msg *SpaceUserConnect) MarshalTo(data []byte) (n int, err error) {
	bw := bytestream.NewByteStream(data)
	return msg.Size(), bw.Marshal(msg)
}

// Unmarshal 反序列化
func (msg *SpaceUserConnect) Unmarshal(data []byte) error {
	br := bytestream.NewByteStream(data)
	return br.Unmarshal(msg)
}

// Size 获取长度
func (msg *SpaceUserConnect) Size() (n int) {
	return bytestream.CalcSize(msg)
}

// SpaceUserConnectSucceedRet 空间玩家专用连接成功
type SpaceUserConnectSucceedRet struct {
}

func (msg *SpaceUserConnectSucceedRet) String() string {
	return fmt.Sprintf("%+v", *msg)
}

// Name 获取消息名称
func (msg *SpaceUserConnectSucceedRet) Name() string {
	return "SpaceUserConnectSucceedRet"
}

// MarshalTo 序列化
func (msg *SpaceUserConnectSucceedRet) MarshalTo(data []byte) (n int, err error) {
	bw := bytestream.NewByteStream(data)
	return msg.Size(), bw.Marshal(msg)
}

// Unmarshal 反序列化
func (msg *SpaceUserConnectSucceedRet) Unmarshal(data []byte) error {
	br := bytestream.NewByteStream(data)
	return br.Unmarshal(msg)
}

// Size 获取长度
func (msg *SpaceUserConnectSucceedRet) Size() (n int) {
	return bytestream.CalcSize(msg)
}

// SyncClock 对时
type SyncClock struct {
	TimeStamp uint32
}

func (msg *SyncClock) String() string {
	return fmt.Sprintf("%+v", *msg)
}

// Name 获取消息名称
func (msg *SyncClock) Name() string {
	return "SyncClock"
}

// MarshalTo 序列化
func (msg *SyncClock) MarshalTo(data []byte) (n int, err error) {
	bw := bytestream.NewByteStream(data)
	return msg.Size(), bw.Marshal(msg)
}

// Unmarshal 反序列化
func (msg *SyncClock) Unmarshal(data []byte) error {
	br := bytestream.NewByteStream(data)
	return br.Unmarshal(msg)
}

// Size 获取长度
func (msg *SyncClock) Size() (n int) {
	return bytestream.CalcSize(msg)
}

//////////////////////////////////////////////////////////

// SyncUserState 同步信息
type SyncUserState struct {
	EntityID uint64
	Data     []byte
}

func (msg *SyncUserState) String() string {
	return fmt.Sprintf("%+v", *msg)
}

// Name 获取消息名称
func (msg *SyncUserState) Name() string {
	return "SyncUserState"
}

// MarshalTo 序列化
func (msg *SyncUserState) MarshalTo(data []byte) (n int, err error) {
	bw := bytestream.NewByteStream(data)
	return msg.Size(), bw.Marshal(msg)
}

// Unmarshal 反序列化
func (msg *SyncUserState) Unmarshal(data []byte) error {
	br := bytestream.NewByteStream(data)
	return br.Unmarshal(msg)
}

// Size 获取长度
func (msg *SyncUserState) Size() (n int) {
	return bytestream.CalcSize(msg)
}

//////////////////////////////////////////////////////////////////////

func NewAOISyncUserState() *AOISyncUserState {
	return &AOISyncUserState{
		//Data: make([]byte, 0, 1000),
		Num:  0,
		EIDS: make([]uint64, 0, 10),
		EDS:  make([][]byte, 0, 10),
	}
}

// AOISyncUserState AOI同步信息
type AOISyncUserState struct {
	Num  uint32
	EIDS []uint64
	EDS  [][]byte
}

func (msg *AOISyncUserState) String() string {
	return fmt.Sprintf("%+v", *msg)
}

// Name 获取消息名称
func (msg *AOISyncUserState) Name() string {
	return "AOISyncUserState"
}

// MarshalTo 序列化
func (msg *AOISyncUserState) MarshalTo(data []byte) (n int, err error) {
	//bw := bytestream.NewByteStream(data)
	//return msg.Size(), bw.Marshal(msg)

	size := msg.Size()
	bw := bytestream.NewByteStream(data)
	bw.WriteUInt32(msg.Num)

	for i := 0; i < int(msg.Num); i++ {
		bw.WriteUInt64(msg.EIDS[i])
		bw.WriteBytes(msg.EDS[i])
	}

	return size, nil
}

// Unmarshal 反序列化
func (msg *AOISyncUserState) Unmarshal(data []byte) error {
	//br := bytestream.NewByteStream(data)
	//return br.Unmarshal(msg)
	return nil
}

// Size 获取长度
func (msg *AOISyncUserState) Size() (n int) {

	sum := 0
	for i := 0; i < len(msg.EDS); i++ {
		sum += len(msg.EDS[i])
	}

	return 4 + len(msg.EIDS)*8 + len(msg.EIDS)*2 + sum
}

// AddData 增加一个玩家数据
func (msg *AOISyncUserState) AddData(id uint64, data []byte) {
	msg.Num++
	msg.EIDS = append(msg.EIDS, id)
	msg.EDS = append(msg.EDS, data)
}

// Clear 清理
func (msg *AOISyncUserState) Clear() {
	msg.Num = 0
	msg.EIDS = msg.EIDS[0:0]
	msg.EDS = msg.EDS[0:0]
}

////////////////////////////////////////////////////////////////

// EntityBaseProps Entity基本属性
type EntityBaseProps struct {
	EntityID      uint64   // 自己的EntityID
	LinkTarget    uint64   // 链接到哪个Entity
	LinkerList    []uint64 // 哪些Entity链接到我
	EntrustTarget uint64   // 委托给谁
	EntrustedList []uint64 // 哪些Entity委托给我
}

func (msg *EntityBaseProps) String() string {
	return fmt.Sprintf("%+v", *msg)
}

// Name 获取消息名称
func (msg *EntityBaseProps) Name() string {
	return "EntityBaseProps"
}

// MarshalTo 序列化
func (msg *EntityBaseProps) MarshalTo(data []byte) (n int, err error) {
	bw := bytestream.NewByteStream(data)

	bw.WriteUInt64(msg.EntityID)
	bw.WriteUInt64(msg.LinkTarget)
	bw.WriteByte(byte(len(msg.LinkerList)))
	for _, id := range msg.LinkerList {
		bw.WriteUInt64(id)
	}

	bw.WriteUInt64(msg.EntrustTarget)
	bw.WriteByte(byte(len(msg.EntrustedList)))
	for _, id := range msg.EntrustedList {
		bw.WriteUInt64(id)
	}

	return msg.Size(), nil
}

// Unmarshal 反序列化
func (msg *EntityBaseProps) Unmarshal(data []byte) error {
	br := bytestream.NewByteStream(data)

	msg.EntityID, _ = br.ReadUInt64()
	msg.LinkTarget, _ = br.ReadUInt64()
	length, _ := br.ReadByte()
	for i := 0; i < int(length); i++ {
		id, _ := br.ReadUInt64()
		msg.LinkerList = append(msg.LinkerList, id)
	}

	msg.EntrustTarget, _ = br.ReadUInt64()
	length, _ = br.ReadByte()
	for i := 0; i < int(length); i++ {
		id, _ := br.ReadUInt64()
		msg.EntrustedList = append(msg.EntrustedList, id)
	}

	return nil
}

// Size 获取长度 8+ 8 + 1 + len(msg.LinkerList)*8 + 8 + 1 + len(msg.EntrustedList)*8
func (msg *EntityBaseProps) Size() (n int) {
	return 26 + len(msg.LinkerList)*8 + len(msg.EntrustedList)*8
}
